package cn.bobohost.market.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;

/**
 * JWT工具类
 */
public class JwtUtil {

    //存活时间（多长时间过期），毫秒
    private static long ttl=1000*60*60*24;//默认24小时钟过期

    /**
     * 载荷中的角色的key
     */
    public static final String JWT_PAYLOAD_ROLES_KEY= "roles";
    /**
     * 普通用户的角色值
     */
//    public static final String JWT_PAYLOAD_ROLES_USER= "user";
    /**
     * 管理员的角色值
     */
//    public static final String JWT_PAYLOAD_ROLES_ADMIN= "admin";

    /**
     * JWT的签名密钥的key
     */
//    private static final String JWT_SECRETKEY_KEY="tensquare_jwt_secretKey";
    /**
     * 正在过期的JWT的签名密钥的key
     */
//    private static final String JWT_SECRETKEY_EXPIRING_KEY="tensquare_jwt_secretKey_expiring";

//    private static final SignatureAlgorithm JWT_SIGNATURE_ALGORITHM_HMAC=SignatureAlgorithm.HS256;


    /**
     * 基于HMAC-SHA加密算法生成jwt的token
     * 说明：HS256 (带有 SHA-256 的 HMAC 是一种对称算法, 双方之间仅共享一个密钥。
     * 由于使用相同的密钥生成签名和验证签名, 因此必须注意确保密钥不被泄密。）
     * 有效负荷 一般包括：已注册信息（registered claims），公开数据(public claims)，私有数据(private claims)
     * @param id
     * @param subject
     * @param roles
     * @return
     */
    public static String generateJwtTokenByHMAC(String id, String subject, String roles, Key secretKey){
        //当前时间
        long nowTimeMillis = System.currentTimeMillis();
        Date now = new Date(nowTimeMillis);

        //构建JwtBuilder
        return Jwts.builder()
                //设置签名算法和key
                .signWith(secretKey)
                //---标准载荷信息
                //唯一标识，这里使用用户id
                .setId(id)
                //主体，这里为用户名
                .setSubject(subject)
                //签发时间
                .setIssuedAt(now)
                //设置token在签发时间之前不可用
                .setNotBefore(now)
                //设置过期时间,毫秒
                .setExpiration(ttl>=0 ? new Date( nowTimeMillis + ttl):null)
                //--自定义载荷内容
                //角色
                .claim(JWT_PAYLOAD_ROLES_KEY, roles)
                //序列化生成token字符串
                .compact()
                ;
    }

    public static Claims parseJwtTokenForClaimsByHMAC(String jwtStr, Key secretKey){
        return  Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwtStr)
                .getBody();
    }

    /**
     * 使用私钥生成token
     * @param id
     * @param subject
     * @param roles
     * @param privateKey
     * @return
     */
    public static String generateJwtTokenByRSA(String id, String subject, String roles,PrivateKey privateKey){
        //当前时间
        long nowTimeMillis = System.currentTimeMillis();
        Date now = new Date(nowTimeMillis);

        //构建JwtBuilder
        return Jwts.builder()
                //设置签名算法和key
                .signWith(privateKey,SignatureAlgorithm.RS256)
                //---标准载荷信息
                //唯一标识，这里使用用户id
                .setId(id)
                //主体，这里为用户名
                .setSubject(subject)
                //签发时间
                .setIssuedAt(now)
                //过期时间,毫秒
                .setExpiration(ttl>=0 ? new Date( nowTimeMillis + ttl):null)
                //--自定义载荷内容
                //角色，可扩展
                .claim(JWT_PAYLOAD_ROLES_KEY, roles)
                .compact()
                ;
    }


    /**
     * 公钥解析token
     * @param jwtToken
     * @param publicKey 公钥
     * @return
     */
    public static Claims parseJwtTokenForClaimsByRSA(String jwtToken,PublicKey publicKey){
        return  Jwts.parser()
                .setSigningKey(publicKey)
                .parseClaimsJws(jwtToken)
                .getBody();
    }


    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) throws Exception {
        //对称式加密签名----随机生成---测试使用
//        Key secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
//        System.out.println("二进制格式的秘钥（字符串）:"+ new String(secretKey.getEncoded(),"iso8859-1"));
//
//        String jwtToken = JwtUtil.generateJwtTokenByHMAC("1001", "Rose", "user", secretKey);
//        System.out.println(jwtToken);
//        Claims claims = JwtUtil.parseJwtTokenForClaimsByHMAC(jwtToken,secretKey);
//        System.out.println(claims.getSubject());


        //----非对称式加密签名
        //#rs算法私钥存放的文件路径
        String privateKeyFilePathStr= "/java/marketproject/ssh/cattongue_rs_key";
        //#rs算法公钥存放的文件路径
        String publicKeyFilePathStr= "/java/marketproject/ssh/cattongue_rs_key.pub";
        //私钥从文件中读取
        PrivateKey privateKey = JwtCryptographyUtil.readPrivateKeyFromFile(privateKeyFilePathStr);
        PublicKey publicKey = JwtCryptographyUtil.readPublicKeyFromFile(publicKeyFilePathStr);

        //---根据私钥生成用户的token
        String userJwtToken = JwtUtil.generateJwtTokenByRSA("18758038388", "yuxin", "user", privateKey);
//        System.out.println("生成的用户token是："+userJwtToken);
        System.out.println("http请求中的header信息的key：Authorization，值是：Bearer "+userJwtToken);
        //---根据共钥解析用户的token（测试）
        Claims claims = JwtUtil.parseJwtTokenForClaimsByRSA(userJwtToken, publicKey);
        System.out.println("解析出来的用户id是："+claims.getId());


//        RedisTemplate redisTemplate=new RedisTemplate();
//        RedisConnection redisConnection=new DefaultStringRedisConnection(new Redis);

    }


}